package com.two.screen.water.balance.utils

import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.graphics.Typeface
import android.os.BatteryManager
import android.os.Build
import android.text.SpannableString
import android.text.Spanned
import android.text.TextUtils
import android.text.style.RelativeSizeSpan
import android.text.style.StyleSpan
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ProgressBar
import android.widget.TextView
import androidx.annotation.Nullable
import androidx.core.content.ContextCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.viewpager.widget.ViewPager
import cc.shinichi.library.ImagePreview
import cc.shinichi.library.tool.image.ImageUtil
import cc.shinichi.library.view.helper.SubsamplingScaleImageViewDragClose
import cc.shinichi.library.view.listener.OnBigImagePageChangeListener
import cc.shinichi.library.view.listener.OnOriginProgressListener
import com.alibaba.android.arouter.launcher.ARouter
import com.allenliu.versionchecklib.v2.AllenVersionChecker
import com.allenliu.versionchecklib.v2.builder.UIData
import com.allenliu.versionchecklib.v2.callback.RequestVersionListener
import com.bigkoo.pickerview.builder.TimePickerBuilder
import com.bigkoo.pickerview.listener.OnTimeSelectListener
import com.bigkoo.pickerview.view.TimePickerView
import com.google.gson.Gson
import com.king.app.dialog.AppDialog
import com.king.app.dialog.AppDialogConfig
import com.king.app.updater.AppUpdater
import com.king.app.updater.http.OkHttpManager
import com.lzy.okgo.OkGo
import com.lzy.okgo.callback.StringCallback
import com.lzy.okgo.model.HttpParams
import com.lzy.okgo.model.Response
import com.two.screen.water.balance.R
import com.two.screen.water.balance.bean.*
import com.two.screen.water.balance.bean.database.UpdateBean
import com.two.screen.water.balance.listener.MyUpdateCallback
import com.two.screen.water.balance.ui.App
import com.two.screen.water.balance.ui.activity.LoginActivity24
import com.two.screen.water.balance.ui.activity.StartUseActivity
import com.two.screen.water.balance.utils.Urls.SIGN_UPDATE_TYPE_BY_SHELL_INSTALL_JGL
import com.youth.banner.Transformer
import org.jsoup.Jsoup
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.util.*
import java.util.Locale.getDefault
import java.util.regex.Pattern
import kotlin.experimental.inv
import kotlin.experimental.xor


/**
 * 创建者     Noel
 * 创建时间   2017/12/21 9:23
 * 描述	      工具类
 */

class CommUtils {

    companion object {
        private val len = 1800
        private var tag = "MobileCheck"
        var MATCH_PARENT = -1
        var WRAP_CONTENT = -2

        val gson: Gson by lazy { Gson() }

        fun println(tag: String? = null, msg: String) {
            // this.tag = tag
            var tmp = tag ?: this.tag
            //if (!App.isDebug) return
            if (msg.length > len) {
                //kotlin.io.println(show)
                kotlin.io.println(tmp + msg.substring(0, len))
                if ((msg.length - len) > len) { //剩下的文本还是大于规定长度
                    println(msg.substring(len, msg.length))
                } else {
                    kotlin.io.println(tmp + msg.substring(len, msg.length))
                }
            } else {
                kotlin.io.println(tmp + msg)
            }
        }

        @SuppressLint("SimpleDateFormat")
        fun getOrderSn(): String {
            //设备号前四位数字化 + 时间 + 8位随机数
            return letterToNum(getAppUUidLast4().uppercase(getDefault())).plus(SimpleDateFormat("yyMMddHHmmssSS").format(Date()))//.plus(String.format("%03d", Random().nextInt(999)))
        }

        // 将字母转换成数字
        fun letterToNum(input: String): String {
            var sb = StringBuilder()
            for (b in input.toByteArray()) {
                sb.append(b)
            }
            return sb.toString()
        }

        fun calcHexXorInvert(hexStr: String): String {
            var crc = 0x00.toByte()
            var byteArray = ByteUtils.hexStr2Bytes(hexStr.replace(" ", ""))
            for (i in byteArray.indices) { //传重量是12个字节，第5条指令是17个字节，报文数据加起来都是29个字节，所以从13开始
                crc = crc.xor(byteArray[i])
            }
            crc = crc.inv()
            return ByteUtils.bytes2HexStr(byteArrayOf(crc))
        }

        fun getBannerAnimation(type: Int): Class<out ViewPager.PageTransformer>? {
            return when (type) {
                0 -> Transformer.Default
                1 -> Transformer.Accordion
                2 -> Transformer.BackgroundToForeground
                3 -> Transformer.ForegroundToBackground
                4 -> Transformer.CubeIn
                5 -> Transformer.CubeOut
                6 -> Transformer.DepthPage
                7 -> Transformer.FlipHorizontal
                8 -> Transformer.FlipVertical
                9 -> Transformer.RotateDown
                10 -> Transformer.RotateUp
                11 -> Transformer.ScaleInOut
                12 -> Transformer.Stack
                13 -> Transformer.Tablet
                14 -> Transformer.ZoomIn
                15 -> Transformer.ZoomOutSlide
                16 -> Transformer.ZoomOut
                else -> getBannerAnimation(Random().nextInt(16))
            }
        }

        @Synchronized
        fun getPackageName(): String? {
            try {
                val packageManager: PackageManager = App.context!!.packageManager
                val packageInfo: PackageInfo = packageManager.getPackageInfo(
                    App.context!!.packageName, 0
                )
                return packageInfo.packageName
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return null
        }

        //获取设备号
        fun getAppUUid(): String {
//            var uuid = SPUtils.getString("PREF_KEY_UUID")
//            if (uuid.isNullOrBlank()) {
//                uuid = UUID.randomUUID().toString().toUpperCase(Locale.ROOT)//.substring(0,8)
//                SPUtils.putString("PREF_KEY_UUID", uuid)
//            }
            return UniqueIDUtils.getUniqueID().uppercase(getDefault())
        }

        fun dp2px(dpValue: Float): Int {
            val density = App.context!!.resources.displayMetrics.density
            return (density * dpValue + 0.5).toInt()
        }

        fun dp2px(dpValue: Int): Int {
            val density = App.context!!.resources.displayMetrics.density
            return (density * dpValue + 0.5).toInt()
        }

        fun dp2pxF(dpValue: Float): Float {
            val density = App.context!!.resources.displayMetrics.density
            return density * dpValue
        }

        fun px2dip(pxValue: Float): Int {
            val scale = App.context!!.resources.displayMetrics.density
            return (pxValue / scale + 0.5f).toInt()
        }

        fun sp2px(sp: Int): Int {
            return TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_SP, sp.toFloat(), App.context!!.resources.displayMetrics
            )
                .toInt()
        }

        fun sp2pxF(sp: Int): Float {
            return TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_SP, sp.toFloat(), App.context!!.resources.displayMetrics
            )
        }

        /**
         * method is used for checking valid email id formatDate.
         * @param email
         * @return boolean true for valid false for invalid
         */
        fun isEmailValid(email: String): Boolean {
            var isValid = false
            val expression = "^[\\w\\.-]+@([\\w\\-]+\\.)+[A-Z]{2,4}$"

            val pattern = Pattern.compile(expression, Pattern.CASE_INSENSITIVE)
            val matcher = pattern.matcher(email)
            if (matcher.matches()) {
                isValid = true
            }
            return isValid
        }


        fun creatItemView(context: Context, layout: Int, w: Int, h: Int): View {
            val view = View.inflate(context, layout, null)
            view.layoutParams = DrawerLayout.LayoutParams(w, h)
            return view
        }


        /**
         * 获取App版本码
         *
         * @return App版本码
         */
        fun getAppVersionCode(): Long {
            return getAppVersionCode(App.context!!, App.context!!.packageName)
        }

        /**
         * 获取App版本码
         *
         * @param context     上下文
         * @param packageName 包名
         * @return App版本码
         */
        fun getAppVersionCode(context: Context, packageName: String): Long {
            if (TextUtils.isEmpty(packageName)) {
                return -1
            }
            return try {
                val pm = context.packageManager
                val pi = pm.getPackageInfo(packageName, 0)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                    pi?.longVersionCode
                        ?: -1
                } else {
                    pi?.versionCode?.toLong() ?: -1
                }
            } catch (e: PackageManager.NameNotFoundException) {
                e.printStackTrace()
                -1
            }

        }


        fun toYMD(ms: Long?, pattern: String = "yyyy-MM-dd"): String {
            return try {
                if (ms!! == 0L) return ""
                var data = Date(ms * 1000)
                SimpleDateFormat(pattern, getDefault()).format(data)
            } catch (e: Exception) {
                ""
            }
        }

        fun toYMD_HMS(ms: Long?, pattern: String = "yyyy-MM-dd HH:mm:ss"): String {
            return try {
                if (ms!! == 0L) return ""
                var data = Date(ms * 1000)
                SimpleDateFormat(pattern, getDefault()).format(data)
            } catch (e: Exception) {
                ""
            }
        }

        fun toYMD(ymd: String?, pattern: String = "yyyy-MM-dd"): String {
            return try {
                var ms = ymd?.toLong()
                if (ms!! == 0L) return ""
                var data = Date(ms * 1000)
                SimpleDateFormat(pattern, getDefault()).format(data)
            } catch (e: Exception) {
                ""
            }
        }

        fun toYMDHM(ms: Long?): String {
            return try {
                if (ms!! == 0L) return ""
                var data = Date(ms * 1000)
                SimpleDateFormat("yyyy-MM-dd HH:mm", getDefault()).format(data)
            } catch (e: Exception) {
                ""
            }
        }

        @SuppressLint("SimpleDateFormat")
        //年月日 转 秒
        fun YMD2s(ymd: String?, pattern: String = "yyyy-MM-dd"): Long? {
            return try {
                if (ymd == null) null
                else {
                    val simpleDateFormat = SimpleDateFormat(pattern)
                    simpleDateFormat.parse(ymd).time / 1000
                }
            } catch (e: Exception) {
                null
            }
        }

        val df: DecimalFormat by lazy { DecimalFormat(".##") }
        fun save2floatNoZero(float: Float): Float {
            return df.format(float)
                .toFloat()
        }

        fun float2Str(float: Float?): String {
            return try {
                float.toString()
            } catch (e: Exception) {
                "0"
            }
        }

        fun encodeByMD5(text: String): String {
            try {
                //获取md5加密对象
                val instance: MessageDigest = MessageDigest.getInstance("MD5")
                //对字符串加密，返回字节数组
                val digest: ByteArray = instance.digest(text.toByteArray())
                var sb: StringBuffer = StringBuffer()
                for (b in digest) {
                    //获取低八位有效值
                    var i: Int = b.toInt() and 0xff
                    //将整数转化为16进制
                    var hexString = Integer.toHexString(i)
                    if (hexString.length < 2) {
                        //如果是一位的话，补0
                        hexString = "0$hexString"
                    }
                    sb.append(hexString)
                }
                return sb.toString()
                    .apply { println("sign", "MD5后：$this") }

            } catch (e: NoSuchAlgorithmException) {
                e.printStackTrace()
            }
            return ""
        }

        //设置边距margin
        fun setMargins(v: View?, l: Int, t: Int, r: Int, b: Int) {
            if (v?.layoutParams is ViewGroup.MarginLayoutParams) {
                val p = v.layoutParams as ViewGroup.MarginLayoutParams
                p.setMargins(dp2px(l), dp2px(t), dp2px(r), dp2px(b))
                v.requestLayout()
            }
        }

        fun setHeight(v: View?, height: Int) {
            if (v?.layoutParams is ViewGroup.MarginLayoutParams) {
                val p = v.layoutParams as ViewGroup.MarginLayoutParams
                p.height = 0
                v.requestLayout()
            }
        }


        //获取设备号后四位
        fun getAppVersionName(): String {
            return try {
                // Get the package info
                var pm = App.context!!.packageManager
                var pi = pm.getPackageInfo(App.context!!.packageName, 0)
                pi.versionName//.plus("::").plus(getAppUUidLast4())
                    ?: "空版本 for Android"
            } catch (e: Exception) {
                "未知版本好 for Android"
            }
        }

        //获取设备号后四位
        fun getAppUUidLast4(): String {
            val appUUid = getAppUUid()
            val subUUid = appUUid.substring(0, 4)
            println("getAppUUidLast4:", "appUUid:$appUUid,subUUid:$subUUid")
            return subUUid
        }

        //根据秒转成 Calendar
        fun getCalendarBySeconds(any: Any?): Calendar? {
            return try {
                Calendar.getInstance()
                    .apply {
                        if ((any as Long) == 0L) return null
                        timeInMillis = any * 1000
                    }
            } catch (e: Exception) {
                null
            }
        }

        //年月日
        fun showTimePicker(
            context: Context,
            picker: TimePickerView?,
            startDate: Calendar? = null,
            endDate: Calendar? = null,
            selectedDate: Calendar? = null,
            l: OnTimeSelectListener? = null
        ): TimePickerView? {
            return if (picker == null) {
                TimePickerBuilder(context, l)
                    //.setTimeSelectChangeListener { Log.i("pvTime", "onTimeSelectChanged") }
                    .setType(booleanArrayOf(true, true, true, false, false, false))
                    .isDialog(true)
                    .setDate(selectedDate)
                    .setRangDate(startDate, endDate)
                    .build()
                    .apply {
                        if (dialog != null) {
                            dialogContainerLayout.layoutParams = FrameLayout.LayoutParams(
                                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM
                            )
                                .apply {

                                    leftMargin = 0
                                    rightMargin = 0
                                }

                            dialog.window?.apply {
                                setWindowAnimations(com.bigkoo.pickerview.R.style.picker_view_slide_anim) //修改动画样式
                                setGravity(Gravity.BOTTOM) //改成Bottom,底部显示
                            }
                        }
                        show()
                    }
            } else {
                picker.show()
                picker
            }

        }

        fun logout(context: Activity?) {
            SPUtils.putToken(null)
            ARouter.getInstance()
                .build(ARouterUtils.StartUseActivity)
                .navigation()
//            context.startActivity(Intent(acty, LoginActivity::class.java))
            context?.overridePendingTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom)
            ActivityCollector.finishAll()
            //acty.finish()
        }

        /*html格式化，取出 img标签 然后添加 宽高 达到显示正常*/
        fun getNewContent(htmltext: String?): String {
            val doc = Jsoup.parse(htmltext)
            val elements = doc.getElementsByTag("img")
            for (element in elements) {
                element.attr("width", "100%").attr("height", "auto")
            }
            return doc.toString()
        }

        fun go2Preview(context: Context, mData: List<String>?, position: Int) {
            /*var tmp = mData?.map {
                var iif = ImageInfo()
                iif.originUrl = it
                iif.thumbnailUrl = it.toThumb()
                iif
            }*/
            mData?.let {
                var ip = ImagePreview.getInstance()
                    // 上下文，必须是activity，不需要担心内存泄漏，本框架已经处理好
                    .setContext(context)
                    // 从第几张图片开始，索引从0开始哦~
                    .setIndex(position)
                    //=================================================================================================
                    // 有三种设置数据集合的方式，根据自己的需求进行三选一：
                    // 1：第一步生成的imageInfo List
                    // .setImageInfoList(tmp)

                    // 2：直接传url List
                    .setImageList(mData)

                    // 3：只有一张图片的情况，可以直接传入这张图片的url
                    //.setImage("http://img.rdxsaj.com/uploads/images/2019-11-05/bb92a00ff8c85c5a683b76756cbdd1a3.jpg")
                    //=================================================================================================

                    // 加载策略，默认为手动模式
                    .setLoadStrategy(ImagePreview.LoadStrategy.AlwaysOrigin)

                    // 保存的文件夹名称，会在SD卡根目录进行文件夹的新建。
                    // (你也可设置嵌套模式，比如："BigImageView/Download"，会在SD卡根目录新建BigImageView文件夹，并在BigImageView文件夹中新建Download文件夹)
                    .setFolderName("食安检查询屏/Download")

                    // 缩放动画时长，单位ms
                    .setZoomTransitionDuration(300)

                    // 是否显示加载失败的Toast
                    .setShowErrorToast(true)

                    // 是否启用点击图片关闭。默认启用
                    .setEnableClickClose(true)
                    // 是否启用下拉关闭。默认不启用
                    .setEnableDragClose(true)
                    // 是否启用上拉关闭。默认不启用
                    .setEnableUpDragClose(true)
                    // 是否显示关闭页面按钮，在页面左下角。默认不显示
                    .setShowCloseButton(true)
                    // 设置关闭按钮图片资源，可不填，默认为库中自带：R.drawable.ic_action_close
                    .setCloseIconResId(R.drawable.ic_action_close)

                    // 是否显示下载按钮，在页面右下角。默认显示
                    .setShowDownButton(false)
                    // 设置下载按钮图片资源，可不填，默认为库中自带：R.drawable.icon_download_new
                    .setDownIconResId(R.drawable.icon_download_new)

                    // 设置是否显示顶部的指示器（1/9）默认显示
                    .setShowIndicator(true)

                    // 设置失败时的占位图，默认为库中自带R.drawable.load_failed，设置为 0 时不显示
                    .setErrorPlaceHolder(R.drawable.load_failed)

                    // 点击回调
                    .setBigImageClickListener { view, position ->
                        // ...
                    }
                    // 长按回调
                    .setBigImageLongClickListener { view, position ->
                        // ...
                        false
                    }
                    // 页面切换回调
                    .setBigImagePageChangeListener(object : OnBigImagePageChangeListener {
                        override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
                        }

                        override fun onPageSelected(position: Int) {
                        }

                        override fun onPageScrollStateChanged(state: Int) {
                        }
                    })

                    //=================================================================================================
                    // 设置查看原图时的百分比样式：库中带有一个样式：ImagePreview.PROGRESS_THEME_CIRCLE_TEXT，使用如下：
                    .setProgressLayoutId(ImagePreview.PROGRESS_THEME_CIRCLE_TEXT, object : OnOriginProgressListener {
                        override fun progress(parentView: View, progress: Int) {
                            // 需要找到进度控件并设置百分比，回调中的parentView即传入的布局的根View，可通过parentView找到控件：
                            val progressBar = parentView.findViewById<ProgressBar>(R.id.sh_progress_view)
                            val textView = parentView.findViewById<TextView>(R.id.sh_progress_text)
                            //textView.textSize = context.resources.getDimension(R.dimen.common_measure_20sp)
                            //textView.setTextColor(CommUtils.getColor(R.color.f6))
                            progressBar.progress = progress
                            val progressText = "$progress%"
                            textView.text = progressText
                        }

                        override fun finish(parentView: View) {
                        }
                    })

                // 使用自定义百分比样式，传入自己的布局，并设置回调，再根据parentView找到进度控件进行百分比的设置：
                //.setProgressLayoutId(R.layout.image_progress_layout_theme_1, new OnOriginProgressListener() {
                //    @Override public void progress(View parentView, int progress) {
                //        Log.d(TAG, "progress: " + progress);
                //
                //        ProgressBar progressBar = parentView.findViewById(R.id.progress_horizontal);
                //        progressBar.setProgress(progress);
                //    }
                //
                //    @Override public void finish(View parentView) {
                //        Log.d(TAG, "finish: ");
                //    }
                //})
                //=================================================================================================

                // 开启预览
                ip.start()
            }
        }

        fun setImageSpec(activity: Activity, imagePath: String, imageView: SubsamplingScaleImageViewDragClose) {
            val isLongImage = ImageUtil.isLongImage(activity, imagePath)
            if (isLongImage) {
                imageView.setMinimumScaleType(SubsamplingScaleImageViewDragClose.SCALE_TYPE_START)
                imageView.minScale = ImageUtil.getLongImageMinScale(activity, imagePath)
                imageView.maxScale = ImageUtil.getLongImageMaxScale(activity, imagePath)
                imageView.setDoubleTapZoomScale(ImageUtil.getLongImageMaxScale(activity, imagePath))
            } else {
                val isWideImage = ImageUtil.isWideImage(activity, imagePath)
                val isSmallImage = ImageUtil.isSmallImage(activity, imagePath)
                if (isWideImage) {
                    imageView.setMinimumScaleType(SubsamplingScaleImageViewDragClose.SCALE_TYPE_CENTER_INSIDE)
                    imageView.minScale = ImagePreview.getInstance().minScale
                    imageView.maxScale = ImagePreview.getInstance().maxScale
                    imageView.setDoubleTapZoomScale(ImageUtil.getWideImageDoubleScale(activity, imagePath))
                } else if (isSmallImage) {
                    imageView.setMinimumScaleType(SubsamplingScaleImageViewDragClose.SCALE_TYPE_CENTER_INSIDE)
                    imageView.minScale = ImageUtil.getSmallImageMinScale(activity, imagePath)
                    imageView.maxScale = ImageUtil.getSmallImageMaxScale(activity, imagePath)
                    imageView.setDoubleTapZoomScale(ImageUtil.getSmallImageMaxScale(activity, imagePath))
                } else {
                    imageView.setMinimumScaleType(SubsamplingScaleImageViewDragClose.SCALE_TYPE_CENTER_INSIDE)
                    imageView.minScale = ImagePreview.getInstance().minScale
                    imageView.maxScale = ImagePreview.getInstance().maxScale
                    imageView.setDoubleTapZoomScale(ImagePreview.getInstance().mediumScale)
                }
            }
        }

        fun getWeekDay(seconds: Long): String? {
            val date = Date(seconds)
            var Week = ""
            val c = Calendar.getInstance()
            c.time = date
            val wek = c[Calendar.DAY_OF_WEEK]
            if (wek == 1) {
                Week += "星期日"
            }
            if (wek == 2) {
                Week += "星期一"
            }
            if (wek == 3) {
                Week += "星期二"
            }
            if (wek == 4) {
                Week += "星期三"
            }
            if (wek == 5) {
                Week += "星期四"
            }
            if (wek == 6) {
                Week += "星期五"
            }
            if (wek == 7) {
                Week += "星期六"
            }
            return Week
        }

        //获取电量状态
        // 获取电池充电状态
        fun getBatteryStatus(): String {
            var filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED);
            var intent = App.context!!.registerReceiver(null, filter);
            var status = intent?.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
            var batteryStatus = when (status) {
                BatteryManager.BATTERY_STATUS_CHARGING -> "充电中"
                BatteryManager.BATTERY_STATUS_DISCHARGING -> "放电中"
                BatteryManager.BATTERY_STATUS_FULL -> "已充满"
                BatteryManager.BATTERY_STATUS_UNKNOWN -> "未知状态"
                else -> "未知状态"
            }
            return batteryStatus;
        }


        @SuppressLint("CheckResult")
        fun checkUpdateApp01(url: String?) {
            if (url == null || url.isBlank()) {
                ToastUtil.showToast("更新地址为空!!!")
                return
            }
            AppUpdater
                .Builder(App.context!!)
                .setChannelId(App.context!!.packageName)
                .setUrl(url)
                .setFilename(App.context!!.getString(R.string.app_name).plus("_v").plus((System.currentTimeMillis() / 1000).toString()).plus(".apk"))
                .setVersionCode(getAppVersionCode())
                .setShowNotification(true)
                .setReDownload(true)
                .setSound(true)
                .setDeleteCancelFile(true)
                .setShowPercentage(true)
                .setVibrate(true)
                .setSupportCancelDownload(true)
                .build()
                .setHttpManager(OkHttpManager.getInstance())
                .setUpdateCallback(MyUpdateCallback())
                .start()
        }

        @SuppressLint("CheckResult")
        fun checkUpdateApp01(context: Context, run: Runnable? = null) {
            val marId = SPUtils.getString(Params.mar_id)
            val userId = SPUtils.getString(Params.user_id)
            //println("checkUpdateApp01->", "marId:$marId,userId:$userId")
            OkGo.get<String>(Urls.apkCheckUpdateUrl)
                .params(
                    HttpParams().apply {
                        put(Params.deviceCode, getAppUUid())
                        put(Params.mar_id, marId)
                        put(Params.user_id, userId)
                    })
                .headers(Params.getHeads(sortedMapOf()))
                .execute(object : StringCallback() {
                    override fun onSuccess(response: Response<String>?) {
                        var updateBean = try {
                            gson.fromJson(response?.body().toString(), UpdateBean::class.java)
                        } catch (e: Exception) {
                            UpdateBean()
                        }
                        var data = updateBean.data
                        if (data != null) {
                            val appVersionCode = getAppVersionCode()
                            if (appVersionCode < data.versionCode) {
                                val config = AppDialogConfig(context)
                                config.setTitle("发现新的版本")
                                    .setConfirm("升级") //旧版本使用setOk
                                    .setCancel("下次")
                                    .setContent("当前版本是:${getAppVersionCode()}\n新的版本是:${data.versionCode}")
                                    .setOnClickConfirm {
                                        AppUpdater
                                            .Builder(App.context!!)
                                            .setChannelId(App.context!!.packageName)
                                            .setUrl(data.url ?: "")
                                            .setFilename(App.context!!.getString(R.string.app_name).plus("_v").plus(data.versionCode).plus(".apk"))
                                            .setVersionCode(appVersionCode)
                                            .setShowNotification(true)
                                            .setReDownload(true)
                                            .setSound(true)
                                            .setDeleteCancelFile(true)
                                            .setShowPercentage(true)
                                            .setVibrate(true)
                                            .setSupportCancelDownload(true)
                                            .build()
                                            .setHttpManager(OkHttpManager.getInstance())
                                            //.setUpdateCallback(MyUpdateCallback())
                                            .start()
                                        AppDialog.INSTANCE.dismissDialog();
                                    }
                                AppDialog.INSTANCE.showDialog(context, config)
                            }
                        }
                    }

                    override fun onError(response: Response<String>?) {
                        ToastUtil.showToast(response?.exception?.toString() ?: "更新失败!")
                    }
                })
        }

        fun checkUpdateApp(run: Runnable? = null) {
            AllenVersionChecker.getInstance().cancelAllMission(App.context)
            var update = AllenVersionChecker
                .getInstance()
                .requestVersion()
                .setRequestUrl(Urls.apkCheckUpdateUrl)
                .request(object : RequestVersionListener {
                    @Nullable
                    override fun onRequestVersionSuccess(result: String?): UIData? {
                        var data = try {
                            gson.fromJson(result, UpdateInfo::class.java)?.data
                        } catch (e: Exception) {
                            UpdateInfo()
                        }
                        when (Urls.updateType) {
                            SIGN_UPDATE_TYPE_BY_SHELL_INSTALL_JGL -> {
                                return if (getAppVersionCode() < data?.signVersionJgl?.versionCode ?: 1) {
                                    UIData.create()
                                        .setDownloadUrl(data?.signVersionJgl?.url)
                                } else {
                                    //自动登录
                                    run?.run()
                                    null
                                }
                            }
                            else -> {
                                return if (getAppVersionCode() < data?.versionCode ?: 1) {
                                    UIData.create()
                                        .setDownloadUrl(data?.url)
                                } else {
                                    //自动登录
                                    run?.run()
                                    null
                                }
                            }
                        }
                    }

                    override fun onRequestVersionFailure(message: String) {
                        run?.run()
                    }
                })
                .setDownloadAPKPath(ApkHelper.getDownloadApkCachePath())
                .setApkName(App.context!!.getString(R.string.app_name))
                .setDirectDownload(true)
                .setShowNotification(true)
                .setShowDownloadingDialog(false)
                .setShowDownloadFailDialog(true)
                .setForceRedownload(false)
            when (Urls.updateType) {
                Urls.NOT_SIGN_UPDATE_TYPE_BY_SHELL_INSTALL, SIGN_UPDATE_TYPE_BY_SHELL_INSTALL_JGL -> {
                    //android 6板
                    update.setCustomDownloadInstallListener { context, apk ->
                        ShellUtils.execAutoRoot("/system/bin/pm install -r " + apk.path)
                    }.executeMission(App.context)
                }
                Urls.NOT_SIGN_UPDATE_TYPE_BY_ANDROID_CODE_INSTALL -> {
//                    update.setCustomDownloadInstallListener { context, apk ->
//                        //android 5板
//                        var intent = Intent(Intent.ACTION_VIEW)
//                        intent.setDataAndType(apk, "application/vnd.android.package-archive")
//                        intent.putExtra("IMPLUS_INSTALL", "SILENT_INSTALL")
//                        activity.startActivity(intent)
//                    }.executeMission(App.context)
                    update.executeMission(App.context)
                }
                else -> {
                    update.executeMission(App.context)
                }
            }
        }

        var mLogoutDialog: AlertDialog? = null
        fun showLogoutDialog(acty: Activity?, msg: String) {
            //去掉本地token之类信息
            SPUtils.putToken(null)
            if (acty != null) {
                if (mLogoutDialog == null) {
                    mLogoutDialog = AlertDialog.Builder(acty)
                        .setMessage(/*String.format(acty.getString(R.string.login_expired), msg)*/msg)
                        .setCancelable(false)
                        .setPositiveButton(R.string.confirm) { dialog, _ -> goBackLoginActivity(acty) }
                        .create()
                }
                if (mLogoutDialog != null && !mLogoutDialog!!.isShowing) {
                    mLogoutDialog?.show()
                }
            } else {
                ToastUtil.showToast(msg)
            }
        }

        /*返回登录页面*/
        fun goBackLoginActivity(acty: Activity) {
            mLogoutDialog?.dismiss()
            mLogoutDialog = null
            //TODO:退出到登陆
            var intent = Intent(acty, LoginActivity24::class.java)
            acty.startActivity(intent)
            acty.finish()
            acty.overridePendingTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom)
        }


        /*返回第一个页面*/
        fun goBackFirstActivity(context: Context?) {
            var intent = Intent(context, StartUseActivity::class.java)
            context?.startActivity(intent)
            ActivityCollector.finishAll()
        }
    }
}

//扩展方法。去颜色
fun Any?.getColor(ids: Int): Int = ContextCompat.getColor(App.context!!, ids)

fun String?.toThumb(): String? {
    return try {
        var frontStr = this!!.substring(0, this.indexOfLast { it == '.' })
        var laterStr = substring(this.indexOfLast { it == '.' }, this.length)
        frontStr.plus("_thumb")
            .plus(laterStr)
            .apply {
                CommUtils.println("toThumb:", "frontStr:$frontStr,laterStr:$laterStr,whole:$this")
            }
    } catch (e: Exception) {
        this
    }
}

fun String?.toImgList(): List<String> {
    return try {
        when {
            this == null -> emptyList()
            this.isBlank() -> emptyList()
            else -> this.split(",").toList()
        }
    } catch (e: Exception) {
        emptyList()
    }
}

fun String?.str2Double(): Double {
    return try {
        this!!.toDouble()
    } catch (e: Exception) {
        0.0
    }
}

/*
* isIgnoreBlank: 是否忽略空白，是就当有空白也会以逗号分隔。
* */
fun List<String>?.toImgUrl(isIgnoreBlank: Boolean = false): String {
    return try {
        var str = StringBuffer().apply sb@{
            this@toImgUrl!!.forEach {
                when {
                    isIgnoreBlank -> append(it).append(",")
                    it.isNotBlank() -> append(it).append(",")
                }
            }
        }
            .toString()
        if (str.isNotEmpty()) {
            str.substring(0, str.length - 1)
        } else ""
    } catch (e: Exception) {
        ""
    }
}

/*判断字符串 true: 空和0 */
fun String?.isNullOrZero(): Boolean {
    return try {
        this == null || this.isBlank() || this.toInt() == 0
    } catch (e: Exception) {
        false
    }
}

/*如果是null或者blank则返回 无*/
fun String?.isMo(): String {
    return if (this.isNullOrBlank()) "无" else this!!
}


/*请求数据还会状态吗 等于1 就成功*/
fun IndexBean.isGetDataSuccess(): Boolean {
    return when (code) {
        200 -> true
        else -> {
            ToastUtil.showToast(msg)
            false
        }
    }
}

/*请求数据还会状态吗 等于1 就成功*/
fun ServerGoods.isGetDataSuccess(): Boolean {
    return when (code) {
        200 -> true
        else -> {
            ToastUtil.showToast(msg)
            false
        }
    }
}


/*判断字符串 为空返回“暂无”*/
fun String?.isNotAvailable(): String {
    return try {
        if (this == null || this == "null" || this.isBlank() || this.isEmpty()) "暂无" else this
    } catch (e: Exception) {
        "暂无"
    }
}


fun TextView.formatTimes(t1: String?, t2: String?, proportion: Float = 2f) {
    try {
        var ss = SpannableString(t1.plus("\n").plus(t2))
        ss.setSpan(RelativeSizeSpan(proportion), 0, t1!!.length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
        ss.setSpan(StyleSpan(Typeface.BOLD), 0, t1.length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
        this.text = ss
    } catch (e: Exception) {
        //var ss = SpannableString(0.toString().plus(t2))
        //ss.setSpan(RelativeSizeSpan(1.2f), 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
        this.text = t1.plus("\n").plus(t2)
    }
    if (t1 == null || t2 == null) visibility = View.GONE
}
